import { Container } from './Container'
import { Clazz, Provider, Scope } from './Declaration'

export interface BindStage<T> {
  to(clazz: Clazz<T>): ToStage<T>
}

export interface ToStage<T> {
  inSingletonScope(): FinalStage

  inTransientScope(): FinalStage
}

export interface FinalStage {}

export class FinalStageImp<T> implements BindStage<T>, ToStage<T>, FinalStage {
  private token: string
  private builder: Provider<T> = { scope: Scope.Singleton }
  private container: Container

  constructor(token: string, container: Container) {
    this.token = token
    this.container = container
  }

  to(clazz: Clazz<T>): ToStage<T> {
    this.builder.clazz = clazz
    return this
  }

  inSingletonScope(): FinalStage {
    return this.register(Scope.Singleton)
  }

  inTransientScope(): FinalStage {
    return this.register(Scope.Transient)
  }

  private register(scope: Scope): FinalStage {
    this.builder.scope = scope
    this.container.register(this.token, this.builder)
    return this
  }
}